Orianna is a great swimmer and she's going to a
swimming competition this month and needs your help as she is highly paranoic
about the results of the competition.
The competition consists in some sort of evaluations,
every judge makes a score and, based on that score and the score of other
contestants she will get a score belonging to her results, those scores are
final, meaning that will not change in the competition.
Orianna requires this solution with urgency, she is
getting evaluated on a lot of ways and she is very worried about her results,
so she wants to know what is the worst score from an evaluation A to other
evaluation B inclusive.
Input. The first line will start with an
integer t (1 ≤ t ≤ 100) representing the t test cases, then, t cases will follow, each of the cases starts with two integers n and q (1 ≤ n, q ≤ 105), denoting the
number of evaluations Orianna had, then, n
integers will follow denoting the score on each evaluation (from -109
to 109), after that, q
queries will begin, each query consist on two integers A and B (1 ≤ A
≤ B ≤ n).
Output. You must output the string “Scenario #i:“, a blank line and
then the result of each query, remember, Orianna is interested on the worst
score from evaluation A to evaluation B inclusive.
Sample Input
2
5 3
1 2 3 4 5
1 5
1 3
2 4
5 3
1 -2 -4 3
-5
1 5
1 3
2 4
Sample Output
Scenario #1:
1
1
2
Scenario #2:
-5
-4
-4
ñòðóêòóðû äàííûõ – RMQ
 çàäà÷å ñëåäóåò
ðåàëèçîâàòü çàïðîñû ìèíèìóìà íà îòðåçêàõ. Ïðè ýòîì ñàì ìàññèâ ÷èñåë îñòàåòñÿ
ñòàòè÷åñêèì. Ðåàëèçóåì ñòðóêòóðó äàííûõ RMQ.
Ðåàëèçàöèÿ àëãîðèòìà
#include <cstdio>
#include <cmath>
#include <vector>
#define MAX 100010
#define LOGMAX 17
using namespace
std;
int mas[MAX][LOGMAX], arr[MAX];
int t, tests, n, i, q, a, b;
void Build_RMQ_Array(int *b)
{
int i, j;
for (i = 1; i <= n; i++) mas[i][0] = b[i];
for (j = 1; (1 << j) <= n; j++)
for (i = 1; i + (1 << j) - 1 <= n; i++)
if (mas[i][j - 1] < mas[i + (1 << (j -
1))][j - 1])
mas[i][j] =
mas[i][j - 1];
else mas[i][j] = mas[i + (1 << (j - 1))][j -
1];
}
int RMQ(int
i, int j)
{
int k = (int)(log(1.0
* j - i + 1) / log(2.0));
int res = mas[i][k];
if (mas[j - (1<<k) + 1][k] < res) res =
mas[j - (1<<k) + 1][k];
return res;
}
int main(void)
{
scanf("%d",&tests);
for(t = 1; t <= tests; t++)
{
scanf("%d %d",&n,&q);
for(i = 1; i <= n; i++) scanf("%d",&arr[i]);
Build_RMQ_Array(arr);
printf("Scenario #%d:\n\n",t);
for(i = 0; i < q; i++)
{
scanf("%d %d",&a,&b);
printf("%d\n",RMQ(a,b));
}
}
return 0;
}
Ðåàëèçàöèÿ ïðè ïîìîùè äåðåâà îòðåçêîâ
#include <cstdio>
#include <algorithm>
#define MAX 100010
#define INF 2100000000
using namespace
std;
int SegTree[4*MAX] = {0};
int i, n, tests, t, q, a, b;
int mas[MAX];
void BuildTree(int
*a, int v, int
Left, int Right)
{
if (Left == Right)
SegTree[v] =
a[Left];
else
{
int Middle = (Left + Right) / 2;
BuildTree(a, v*2,
Left, Middle);
BuildTree(a, v*2+1,
Middle+1, Right);
SegTree[v] =
min(SegTree[v*2],SegTree[v*2+1]);
}
}
int GetMin(int
v, int LeftPos, int
RightPos, int Left, int
Right)
{
if (Left > Right) return
INF;
if ((Left == LeftPos) && (Right == RightPos))
return SegTree[v];
int Middle = (LeftPos + RightPos) / 2;
return min(GetMin(v*2, LeftPos, Middle, Left,
min(Right,Middle)),
GetMin(v*2+1, Middle+1, RightPos, max(Left,Middle+1), Right));
}
int main(void)
{
scanf("%d",&tests);
for(t = 1; t <= tests; t++)
{
scanf("%d %d",&n,&q);
for(i = 1; i <= n; i++) scanf("%d",&mas[i]);
BuildTree(mas,1,1,n);
printf("Scenario #%d:\n\n",t);
for(i = 0; i < q; i++)
{
scanf("%d %d",&a,&b);
printf("%d\n",GetMin(1,1,n,a,b));
}
}
return 0;
}